<template>
  <div style="width: 100%; height: 100%"></div>
</template>

<script>
import {
  Scene,
  PerspectiveCamera,
  WebGLRenderer,
  Vector3,
  PlaneGeometry,
  BoxGeometry,
  SphereGeometry,
  TextureLoader,
  RepeatWrapping,
  Mesh,
  MeshLambertMaterial,
  SpotLight,
  AmbientLight,
  DirectionalLight,
  Color,
  LensFlare,
  AdditiveBlending
} from 'three'
import Detector from 'three/examples/js/Detector'
import grassImg from 'static/grass.png'
import lensflare0 from 'assets/lensflare0.png'
import lensflare3 from 'assets/lensflare3.png'
export default {
  data() {
    return {
      scene: null,
      camera: null,
      renderer: null,
      ele: null,
      width: 0,
      height:0,
      plane: null,
      spotLight: null
    }
  },
  mounted() {
    this.ele = this.$el
    this.width = this.$el.clientWidth
    this.height = this.$el.clientHeight

    if (!Detector.webgl) {
      const warning = Detector.getWebGLErrorMessage()
      this.ele.appendChild(warning)
    }
    this.threeStart()
  },
  methods: {
    threeStart () {
      this.initThree()
      this.initScene()
      this.initCamera()
      this.initPlane()
      this.initLight()
      this.addGeometry()
      this.addLensFlare
      this.render()
    },
    initThree () {
      this.renderer = new WebGLRenderer({
        alpha: true, // alpha为true时，镜头光晕才工作
        antialias : true // 是否弱化锯齿特性，true表示弱化，更消耗cpu
      })
      this.renderer.setSize(this.width, this.height)
      this.ele.appendChild(this.renderer.domElement)
      this.renderer.setClearColor(0x000000)
      this.renderer.shadowMap.enabled = true
    },
    initCamera () {
      this.camera = new PerspectiveCamera(45, this.width / this.height, 0.1, 1000)
      this.camera.position.x = -20
      this.camera.position.y = 10
      this.camera.position.z = 45
      this.camera.lookAt(new Vector3(10, 0, 0))
    },
    initScene () {
      this.scene = new Scene()
    },
    initPlane () {
      let textGrass = new TextureLoader().load(grassImg)
      textGrass.wrapS = RepeatWrapping
      textGrass.wrapT = RepeatWrapping
      textGrass.repeat.set(10, 10)

      const planeGeometry = new PlaneGeometry(1000, 1000, 20, 20)
      const planeMaterial = new MeshLambertMaterial({ map: textGrass })
      this.plane = new Mesh(planeGeometry, planeMaterial)
      this.plane.receiveShadow = true
      this.plane.rotation.x = -0.5 * Math.PI
      this.plane.position.x = 15
      this.plane.position.y = 0
      this.plane.position.z = 0
      this.scene.add(this.plane)
    },
    initLight () {
      const ambientLight = new AmbientLight(0x1c1c1c)
      this.scene.add(ambientLight)

      this.spotLight = new SpotLight(0xcccccc)
      this.spotLight.position.set(-40, 60, -10)
      this.spotLight.lookAt(this.plane)
      this.scene.add(this.spotLight)

      const directLight = new DirectionalLight('#ffffff')
      directLight.position.set(30, 10, -50)
      directLight.castShadow = true
      directLight.shadow.camera.near = 0.1
      directLight.shadow.camera.far = 100
      directLight.shadow.camera.fov = 50
      directLight.target = this.plane
      directLight.distance = 0
      directLight.shadow.camera.near = 2
      directLight.shadow.camera.far = 200
      directLight.shadow.camera.left = -100
      directLight.shadow.camera.right = 100
      directLight.shadow.camera.top = 100
      directLight.shadow.camera.bottom = -100
      directLight.shadow.width = 2048
      directLight.shadow.height = 2048
      this.scene.add(directLight)
    },
    addGeometry () {
      const material = new MeshLambertMaterial({color: 0xff3333})
      const geom = new BoxGeometry(4, 4, 4)
      const cube = new Mesh(geom, material)
      cube.position.set(-4, 3, 0)
      cube.castShadow = true
      this.scene.add(cube)

      const sphereGeometry = new SphereGeometry(4, 25, 25)
      const sphereMaterial = new MeshLambertMaterial({
        color: 0x7777ff
      })
      const sphere = new Mesh(sphereGeometry, sphereMaterial)
      sphere.position.x = 10
      sphere.position.y = 5
      sphere.position.z = 10
      sphere.castShadow = true
      this.scene.add(sphere)
    },
    addLensFlare () {
      const textureFlare0 = ImageUtils.loadTexture(lensflare0)
      const textureFlare3 = ImageUtils.loadTexture(lensflare3)

      const flareColor = new Color(0xffaacc)
      const lensFlare = new LensFlare(textureFlare0, 350, 0.0, AdditiveBlending, flareColor)

      lensFlare.add(textureFlare3, 60, 0.6, AdditiveBlending)
      lensFlare.add(textureFlare3, 70, 0.7, AdditiveBlending)
      lensFlare.add(textureFlare3, 120, 0.9, AdditiveBlending)
      lensFlare.add(textureFlare3, 70, 1.0, AdditiveBlending)

      lensFlare.position.copy(this.spotLight.position)
      this.scene.add(lensFlare)
    },
    render () {
      this.renderer.render(this.scene, this.camera)
    }
  }
}
</script>
